using System;
using System.Diagnostics;
using System.IO;

using Microsoft.Win32;

namespace Outcoder.Calcium.VSIntegration.Installation
{
	static class Tools
	{
		public static string GetFilePartName(string vsVersion)
		{
			switch (vsVersion)
			{
				case "9.0":
					return "VS2008";
				case "10.0":
					return "VS2010";
				default:
					return "VS" + vsVersion.Replace('.', '_');
			}
		}

		public static string GetVSProjectTemplatesDir(string version, string language, string projectType)
		{
			string installationDir = GetVSInstallationDir(version);
			string result = string.Format("{0}Common7\\IDE\\ProjectTemplates\\{1}\\{2}\\1033\\",
			                              installationDir, language, projectType);
			return result;
		}

		public static string GetVSItemTemplatesDir(string version, string language, string projectType)
		{
			string installationDir = GetVSInstallationDir(version);
			string result = string.Format("{0}Common7\\IDE\\ItemTemplates\\{1}\\{2}\\1033\\",
			                              installationDir, language, projectType);
			return result;
		}

		static string GetVisualStudioInstallationPath(string vsversion, Action<string> logAction)
		{
			string installationPath = null;
			if (Environment.Is64BitOperatingSystem)
			{
				installationPath = (string)Registry.GetValue(
				   "HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\VisualStudio\\10.0\\",
					"InstallDir",
					null);
			}
			else
			{
				installationPath = (string)Registry.GetValue(
		   "HKEY_LOCAL_MACHINE\\SOFTWARE  \\Microsoft\\VisualStudio\\10.0\\",
				  "InstallDir",
				  null);
			}
			return installationPath;

		}

		public static string GetVSInstallationDir(string version)
		{
			RegistryKey regKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\VisualStudio\" + version + @"\Setup\VS");
			try
			{
				string vsInstallationPath = regKey.GetValue("ProductDir").ToString();
				return vsInstallationPath;
			}
			finally
			{
				if (regKey != null)
				{
					regKey.Close();
				}
			}
		}

		public static string GetInstallDir(string vsversion, Action<string> logAction)
		{
			string vsInstallDir = null;
			RegistryKey vskey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\VisualStudio\" + vsversion);
			if (vskey == null)
			{
				logAction("Visual Studio " + vsversion + " not installed (registry)");
			}
			else
			{
				vsInstallDir = vskey.GetValue("InstallDir", "").ToString();
				if (string.IsNullOrEmpty(vsInstallDir))
				{
					logAction("Visual Studio " + vsversion + " not installed (installdir)");
				}
			}
			return vsInstallDir;
		}

		public static bool DeleteFileIfExists(string file)
		{
			if (File.Exists(file))
			{
				File.Delete(file);
				return true;
			}
			return false;
		}

		public static void RunInstallVSTemplates(string vsVersion, Action<string> logAction)
		{
			string vsInstallDir = GetInstallDir(vsVersion, logAction);
			RunInstallTemplatesUsingDir(vsInstallDir, logAction);
		}

		/// <summary>
		/// Installs the templates by calling the Visual Studio Devenv.exe file with the
		/// argument /installvstemplates 
		/// </summary>
		public static void RunInstallTemplatesUsingDir(
			string visualStudioInstallDir, Action<string> logAction)
		{
			logAction("Running Visual Studio InstallVsTemplates");

			ProcessStartInfo startInfo = new ProcessStartInfo
			                             	{
			                             		FileName = visualStudioInstallDir + "devenv.exe",
			                             		Arguments = "/InstallVsTemplates",
			                             		WorkingDirectory = visualStudioInstallDir,
			                             		CreateNoWindow = true,
			                             		UseShellExecute = false,
			                             		RedirectStandardInput = true,
			                             		RedirectStandardOutput = true,
			                             		RedirectStandardError = true
			                             	};

			Process process = new Process { StartInfo = startInfo };

			bool started = process.Start();

			if (started)
			{
				/* Wait for the Devenv.exe to finish. */
				process.WaitForExit();
			}
			else
			{
				throw new ApplicationException("Unable to start Devenv.exe.");
			}
		}
	}
}